#pragma once

#include "fwd.h"
#include "target.h"
#include "config.h"


namespace evm { namespace messaging {

using namespace std;

/* A messaging transport.
 * This is a mostly opaque handle for an underlying messaging transport driver.
 * It has a 'conf' property which is the cfg.ConfigOpts instance used
 * to construct the transport object. */
struct Transport {
    Transport(ConfigOptsPtr conf, DriverPtr driver);

    ~Transport();

    Json send(TargetPtr target, Json&& msg,
              bool wait_for_reply = false, int timeout = -1, int retry = -1);

    void send_notification(TargetPtr target, Json&& msg, int retry = -1);

    ListenerPtr listen(TargetPtr target);

    ListenerPtr listen_for_notifications(const vector<TargetPriority>& targets_and_priorities);

    ConfigOptsPtr conf;

private:
    DriverPtr driver;
};

using TransportPtr = shared_ptr<Transport>;

TransportPtr get_transport(ConfigOptsPtr conf);

}}
